home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS12.ADF
/
C
/
vsprite
/
mygeltools.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-08-05
|
15KB
|
427 lines
#include <exec/types.h>
#include <exec/exec.h>
#include <graphics/gfxmacros.h>
#include <graphics/gels.h>
#include <graphics/collide.h>
#include <intuition/intuition.h>
/*******************************************************************************
* This file is a collection of tools which are used with the vsprite and
* bob software. It contains the following:
*
* ReadyGels( *gelsinfo, *rastport );
* PurgeGels( *gelsinfo );
*
* struct VSprite *MakeVSprite(lineheight,*image,*colorset,x,y,
* wordwidth,imagedepth,flags);
* DeleteVSprite( &VSprite );
*
* struct Bob *MakeBob(bitwidth,lineheight,imagedepth,*image,
* planePick,planeOnOff,x,y)
* DeleteBob( &Bob );
*
* ReadyGels sets up the defaults of the gel system by initializing the
* GelsInfo structure you provide. First it allocates room for and
* links in lastcolor and nextline. It then uses information in your
* RastPort structure to establish boundary collision defaults at
* the outer edges of the raster. It then links together the GelsInfo
* and the RastPort which you provide. Next it allocates space for two
* dummy virtual sprite structures, calls InitGels and SetCollision.
! You must already have run LoadView before ReadyGels is called.
*
* PurgeGels deallocates all memory which ReadyGels and NewGelList have
* allocated. The system will crash if you have not used these
* routines to allocate the space (you cant deallocate something
* which you havent allocated in the first place).
*
* MakeVSprite allocates enough space for and inits a normal vsprite.
* DeleteVSprite deallocates the memory it used.
*
* MakeBob initializes a standard bob and allocates as much memory as is needed
* for a normal bob and its vsprite structure, links them together.
* To find the associated vsprite, look at the back-pointer (see the
* routine doc itself).
* DeleteBob deallocates the memory it used.
*
* Written by Rob Peck, with thanks to Barry Whitebrook and David Lucas.
*
******************************************************************************/
void border_dummy()
{
return;
}
/* Caller passes a pointer to his GelsInfo structure which he wants to init,
* along with a pointer to his IVPArgs. Default init places the topmost
* bottommost etc at the outermost boundaries of callers rastport parameters.
*/
extern struct RastPort *myRast;
struct VSprite *SpriteHead = NULL;
struct VSprite *SpriteTail = NULL;
/*******************************************************************************
* This routine cannot be run until the first LoadView(&view) has been
* executed. InitGels works with an already active View, so LoadView
* must have been run first.
*/
ReadyGels(g, r)
struct RastPort *r;
struct GelsInfo *g;
{
/* Allocate head and tail of list. */
if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
(struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("ReadyGels: No memory for sprite head.\n");
#endif
return(-1);
}
if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
(struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("ReadyGels: No memory for sprite tail.\n");
#endif
return(-1);
}
/* By setting all bits here, it means that there are NO
* reserved sprites. The system can freely use all of the
* hardware sprites for its own purposes. The caller will not be
* trying to independently use any hardware sprites!
*/
g->sprRsrvd = -1;
/* The nextline array is used to hold system information about
* "at which line number on the screen is this hardware sprite
* again going to become available to be given a new vsprite to
* display".
*/
if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
/**/ MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
#ifdef DEBUG
kprintf("ReadyGels: No memory for nextline.\n");
#endif
return(-1);
}
/* In the lastcolor pointer array, the system will store
* a pointer to the color definitions most recently used
* by the system. .... as a reminder, virtual sprites can
* be assigned to any of the real hardware sprites which
* may be available at the time. The vsprite colors will
* be written into the hardware sprite register set for
* the hardware sprite to which that vsprite is assigned.
* This pointer array contains one pointer to the last
* set of three colors (from the vsprite structure *sprColors)
* for each hardware sprite.
*
* As the system is scanning to determine which hardware
* sprite should next be used to represent a vsprite, it
* checks the contents of this array. If a hardware sprite
* is available and already has been assigned this set of
* colors, no color assignment is needed, and therefore
* no color change instructions will be generated for the
* copper list.
*
* If all vsprites use a different set of sprColors, (pointers
* to sprColors are different for all vsprites), then there
* is a limit of 4 vsprites on a horizontal line. If, on
* the other hand, you define, lets say 8 vsprites, with
* 1 and 2 having the same sprColors, 3 and 4 the same as
* each other, 5 and 6 the same as each other, and 7 and 8
* also having the same vsprite colors, then you will be
* able to have all 8 vsprites on the same horizontal line.
*
* In this case, you will be able to put all 8 vsprites on
* the same horizontal line. The reason this helps is that
* the system hardware shares the color registers between pairs
* of hardware sprites. The system thus has enough resources
* to assign all vsprites to hardware sprites in that there
* are 4 color-sets for 8 vsprites, exactly matching the
* hardware maximum capabilities.
*
* Note that lastcolor will not be used for bobs. Just sprites.
*/
if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
#ifdef DEBUG
kprintf("ReadyGels: No memory for lastcolor.\n");
#endif
return(-1);
}
/* This is a table of pointers to the routines which should
* be performed when DoCollision senses a collision. This
* declaration may not be necessary for a basic vsprite with
* no collision detection implemented, but then it makes for
* a complete example.
*/
if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
/**/ collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
#ifdef DEBUG
kprintf("ReadyGels: No memory for collHandler.\n");
#endif
return(-1);
}
/* When any part of the object touches or passes across
* this boundary, it will cause the boundary collision
* routine to be called. This is at smash[0] in the
* collision handler table and is called only if
* DoCollision is called.
*/
g->leftmost = 0;
g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
g->topmost = 0;
g->bottommost = r->BitMap->Rows - 1;
r->GelsInfo = g; /* link together the two structures */
InitGels(SpriteHead, SpriteTail, g );
/* Pointers initialized to the dummy sprites which will be
* used by the system to keep track of the animation system.
*/
SetCollision(0, border_dummy, g);
WaitTOF();
return(0);
}
/*******************************************************************************
* Use this to get rid of the gels stuff when it is not needed any more.
* You must have allocated the gels info stuff (use the ReadyGels routine).
*/
PurgeGels(g)
struct GelsInfo *g;
{
if (g->collHandler != NULL)
FreeMem(g->collHandler, sizeof(struct collTable));
if (g->lastColor != NULL)
FreeMem(g->lastColor, sizeof(LONG) * 8);
if (g->nextLine != NULL)
FreeMem(g->nextLine, sizeof(WORD) * 8);
if (g->gelHead != NULL)
FreeMem(g->gelHead, sizeof(struct VSprite));
if (g->gelTail != NULL)
FreeMem(g->gelTail, sizeof(struct VSprite));
}
/******************************************************************************
* Because MakeVSprite is called by MakeBob, MakeVSprite only creates the
* VSprite,it doesn't add it to the system list. The calling routine must
* do an AddVSprite after it is created.
*/
struct VSprite *MakeVSprite(lineheight, image, colorset, x, y,
wordwidth, imagedepth, flags)
SHORT lineheight; /* how tall is this vsprite? */
WORD *image; /* where is the vsprite image data, should be
twice as many words as the value of lineheight */
WORD *colorset; /* where is the set of three words which describes
the colors that this vsprite can take on? */
SHORT x, y; /* what is its initial onscreen position? */
SHORT wordwidth, imagedepth, flags;
{
struct VSprite *v; /* make a pointer to the vsprite structure which
this routine dynamically allocates */
if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
printf("MakeVSprite: Couldn't allocate VSprite.\n");
#endif
return(0);
}
v->Flags = flags; /* is this a vsprite, not a bob? */
v->Y = y; /* Establish initial position relative to */
v->X = x; /* the Display coordinates. */
v->Height = lineheight; /* user says how high it is */
v->Width = wordwidth; /* a vsprite is always 1 word (16 bits) wide */
/* There are two kinds of depth... the depth of the image itself, and the
* depth of the playfield into which it will be drawn. The image depth
* says how much data space will be needed to store an image if it's
* dynamically allocated. The playfield depth establishes how much space
* will be needed to save and restore the background when a bob is drawn.
* A vsprite is always 2 planes deep, but if it's being used to make a
* bob, it may be deeper...
*/
v->Depth = imagedepth;
/* Assume that user at least has a default boundary collision
* routine.... bit 1 of this mask is reserved for boundary collision
* detect during DoCollision(). The only collisions reported will be
* with the borders. The caller can change all this later.
*/
v->MeMask = 1;
v->HitMask = 1;
v->ImageData = image; /* Caller says where to find the image. */
/* Show system where to find a mask which is a squished down version
* of the vsprite (allows for fast horizontal border collision detect).
*/
if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
/**/ MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("MakeVSprite: Couldn't allocate BorderLine.\n");
#endif
return(0);
}
/* Show system where to find the mask which contains a 1 bit for any
* position in the object in any plane where there is a 1 bit (all planes
* OR'ed together).
*/
if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
MEMF_CHIP | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("MakeVSprite: Couldn't allocate CollMask.\n");
#endif
return(0);
}
/* This isn't used for a Bob, just a VSprite. It's where the
* Caller says where to find the VSprites colors.
*/
v->SprColors = colorset;
/* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
v->PlanePick = 0x00;
v->PlaneOnOff = 0x00;
InitMasks(v); /* create the collMask and borderLine */
return(v);
}
struct Bob *MakeBob(bitwidth,lineheight,imagedepth,image,
planePick,planeOnOff, x,y, flags)
SHORT bitwidth,lineheight,imagedepth,planePick,planeOnOff,x,y,flags;
WORD *image;
{
struct Bob *b;
struct VSprite *v;
SHORT wordwidth;
wordwidth = (bitwidth+15)/16;
/* Create a vsprite for this bob, it will need to be deallocated
* later (freed) when this bob gets deleted.
* Note: No color set for bobs.
*/
if ((v = MakeVSprite(lineheight, image, NULL, x, y, wordwidth,
imagedepth, flags)) == 0) {
#ifdef DEBUG
kprintf("MakeBob: MakeVSprite failed.\n");
#endif
return(0);
}
/* Caller selects which bit planes into which the image is drawn. */
v->PlanePick = planePick;
/* What happens to the bit planes into which the image is not drawn. */
v->PlaneOnOff = planeOnOff;
if ((b = (struct Bob *)AllocMem(sizeof(struct Bob),
MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("MakeBob: Couldn't allocate bob.\n");
#endif
return(0);
}
v->VSBob = b; /* Link together the bob and its vsprite structures */
b->Flags = 0; /* Not part of an animation (BOBISCOMP) and don't keep the
image present after bob is removed (SAVEBOB) */
/* Tell where to save background. Must have enough space for as many
* bitplanes deep as the display into which everything is being drawn.
*/
if ((b->SaveBuffer = (WORD *)AllocMem(sizeof(SHORT) * wordwidth
/**/ * lineheight * imagedepth, MEMF_CHIP | MEMF_CLEAR)) == 0) {
#ifdef DEBUG
kprintf("MakeBob: Couldn't allocate save buffer.\n");
#endif
return(0);
}
b->ImageShadow = v->CollMask;
/* Interbob priorities are set such that the earliest defined bobs have
* the lowest priority, last bob defined is on top.
*/
b->Before = NULL; /* Let the caller worry about priority later. */
b->After = NULL;
b->BobVSprite = v;
/* InitMasks does not preset the imageShadow ... user may elect to use
* the collMask or to create his own version of a shadow, although it
* is usually the same.
*/
b->BobComp = NULL; /* this is not part of an animation */
b->DBuffer = NULL; /* this is not double buffered */
/* Return a pointer to this newly created bob for additional caller
* interaction or for AddBob(b);
*/
return(b);
}
/* Deallocate memory which has been allocated by the routine MakeGel. */
/* assumes images and imageshadow deallocated elsewhere */
DeleteGel(v)
struct VSprite *v;
{
if (v != NULL) {
if (v->VSBob != NULL) {
if (v->VSBob->SaveBuffer != NULL) {
FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
* v->Height * v->Depth);
}
if (v->VSBob->DBuffer != NULL) {
if (v->VSBob->DBuffer->BufBuffer != 0) {
FreeMem(v->VSBob->DBuffer->BufBuffer,
sizeof(SHORT) * v->Width * v->Height * v->Depth);
}
FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
}
FreeMem( v->VSBob, sizeof(struct Bob));
}
if (v->CollMask != NULL) {
FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
}
if (v->BorderLine != NULL) {
FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
}
FreeMem(v, sizeof(struct VSprite));
}
}